import java.awt.Image;
import java.awt.Graphics;
import java.awt.Color;

/**
*	A class representing a cell of the board.
**/
public class  Cell
{


	/**
	*	Used to cycle through the RMB states.
	*	(i.e. STATE_CLEAN, STATE_FLAGGED and STATE_MARKED).
	*
	**/

	public static final int TOTAL_RMB_STATES = 3;
	/**
	*	
	**/
	public static final int STATE_CLEAN = 0;
	public static final int STATE_FLAGGED = 1;
	public static final int STATE_MARKED = 2;
	public static final int STATE_VISITED = 3;
	public static final int STATE_PRESSED = 4;
	public static final int STATE_DISPLAY_MINE = 5;
	public static final int STATE_WRONGLY_FLAGGED = 6;


	public static final int WIDTH = 16;
	public static final int HEIGHT = 16;


	private static final int PIXEL_BORDER_X = 2;


	/**
	*	Does this cell contain a mine..?
	**/
	private boolean mined;

	
	/**
	*	What is this cells' current state?
	**/

	private int state;

	/**
	*	The number of neighbouring cells that are mines.
	**/
	private int numberNeighbourMines;

	public Cell(boolean mined){

		this.mined = mined;
		state = STATE_CLEAN;

	}

	public int getNumborOfNeighbourMines(){

		return numberNeighbourMines;	

	}
	
	public void setNumberOfNeighbourMines(int new_num){

		numberNeighbourMines = new_num;

	}

	public boolean isMined()
	{

		return mined;

	}

	public int getState()
	{
	
		return state;

	}

	/**
	*	visit this cell
	**/
	public void visit()
	{

		if(state == STATE_CLEAN ||
			state == STATE_PRESSED)
		{
			state = STATE_VISITED;
		}

	}

	/**
	*	Mark this cell (with a '?')
	**/
	public void mark()
	{

		state = STATE_MARKED;

	}

	/**
	* Flag this cell
	**/
	public void flag()
	{

		state = STATE_FLAGGED;

	}

	/**
	*	'press' this cell.
	**/
	public void press()
	{

		if(state != STATE_VISITED)
		{
			state = STATE_PRESSED;
		}

	}

	/**
	*	Display the mine if the game is over.
	**/
	public void displayMine()
	{
		if(mined && state != STATE_FLAGGED &&
			state != STATE_VISITED)
		{
			state = STATE_DISPLAY_MINE;
		}

		if(!mined && state == STATE_FLAGGED)//wrongly flagged.
		{
			state = STATE_WRONGLY_FLAGGED;
		}
	}


	/**
	*	'clean' the state of this cell.
	**/
	public void clean()
	{
	
		if(state != STATE_PRESSED)
		{
			return;
		}
		state = STATE_CLEAN;

	}


	/**
	*	Cycle through the RMB states.
	*	(i.e. STATE_CLEAN, STATE_FLAGGED and STATE_MARKED).
	*
	**/
	
	public void cycleRMBState()
	{
	
		if(state >= TOTAL_RMB_STATES)
		{
			return;
		}

		state ++;
		state = state % TOTAL_RMB_STATES;

	}


	/**
	*	Display the cell to the specified graphics device, at the specified 
	*	location.
	**/
	public void display(Graphics g, int x, int y)
	{

//		System.out.println("State for "+x+","+y+": "+state);
		switch(state){

			case STATE_CLEAN:
				g.drawImage(Game.images[Game.IMG_CELL_UNTOUCHED],x,y,null);
				return;
			case STATE_FLAGGED:
				g.drawImage(Game.images[Game.IMG_CELL_UNTOUCHED],x,y,null);
				g.drawImage(Game.images[Game.IMG_FLAG],x,y,null);
				return;
			case STATE_MARKED:
				g.drawImage(Game.images[Game.IMG_CELL_UNTOUCHED],x,y,null);
				g.drawImage(Game.images[Game.IMG_QUESTION_MARK],x,y,null);
				return;
			case STATE_PRESSED:
				g.drawImage(Game.images[Game.IMG_CELL_TOUCHED],x,y,null);
				return;
			case STATE_VISITED:
				if(mined)
				{
					g.setColor(Color.RED);
					g.fillRect(x,y,Cell.WIDTH,Cell.HEIGHT);
					g.drawImage(Game.images[Game.IMG_MINE],x,y,null);
				}else{
					g.drawImage(Game.images[Game.IMG_CELL_TOUCHED],x,y,null);
					if(numberNeighbourMines > 0)
					{
						g.drawImage(Game.images[numberNeighbourMines],x,y,null);
					}
				}
				return;
			case STATE_DISPLAY_MINE:
				g.drawImage(Game.images[Game.IMG_CELL_TOUCHED],x,y,null);
				g.drawImage(Game.images[Game.IMG_MINE],x,y,null);
				return;

			case STATE_WRONGLY_FLAGGED:
				g.drawImage(Game.images[Game.IMG_CELL_TOUCHED],x,y,null);
				g.drawImage(Game.images[Game.IMG_MINE],x,y,null);
				g.setColor(Color.RED);

				// \
				g.drawLine(x+PIXEL_BORDER_X,y + PIXEL_BORDER_X, 
						x + WIDTH - (PIXEL_BORDER_X ) -1,
						y + HEIGHT - (PIXEL_BORDER_X ));
				g.drawLine(x+PIXEL_BORDER_X+1,y + PIXEL_BORDER_X, 
						x + WIDTH - (PIXEL_BORDER_X ),
						y + HEIGHT - (PIXEL_BORDER_X ));
				// /

				g.drawLine(x + WIDTH - (PIXEL_BORDER_X )-1,y + PIXEL_BORDER_X, 
						x  + (PIXEL_BORDER_X  ) ,
						y + HEIGHT - (PIXEL_BORDER_X ));
				g.drawLine(x + WIDTH - (PIXEL_BORDER_X ) ,y + PIXEL_BORDER_X, 
						x + (PIXEL_BORDER_X  )+1,
						y + HEIGHT - (PIXEL_BORDER_X ));

				return;
				
		}

	}

	public int getPrologVersionOfCell(){
		if(state == STATE_VISITED)		return numberNeighbourMines;
		else							return -1;
	}
}

